Skip to content

Add opt-in IEEE 802.11 Radiotap PCAP capture - #1130

Open
mgonzalezlopezudc wants to merge 5 commits into
inet-framework:masterfrom
mgonzalezlopezudc:feat/ieee80211-radiotap-pcap
Open

mgonzalezlopezudc wants to merge 5 commits into
inet-framework:masterfrom
mgonzalezlopezudc:feat/ieee80211-radiotap-pcap

Conversation

@mgonzalezlopezudc

@mgonzalezlopezudc mgonzalezlopezudc commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Add protocol-specific PCAP capture adapters and an opt-in IEEE 802.11 Radiotap
adapter. Bare IEEE 802.11 DLT 105 remains the default; enabling both
enableProtocolSpecificCaptureAdapters and packet conversion selects DLT 127.

  • Export available legacy, HT and VHT SU PHY metadata.
  • Split typed A-MPDUs into MPDU records with deterministic inbound aggregate
    references; preserve malformed aggregates as whole-PSDU records.
  • Keep wireless observation translation and WLAN-specific encoding outside the
    generic recorder.
  • Write metadata prefixes and packet slices without allocating temporary packets.
  • Honor finite PCAPng capture limits and preserve zero-as-unlimited behavior.
  • Preserve existing packet-only writePacket overrides for filtering and
    replacement before adapter records are generated.

VHT MU, HE and EHT metadata remain outside this PR's scope.

The adapter preserves short-preamble metadata independently of FCS flags.
Tests cover request/indication tags and transmission precedence. The registry
exposes a single protocol-resolution operation used by the recorder.

Reading order

Commit Change
acef126fc4 Honor finite PCAPng capture limits
3b21e6ce45 Add prefix-aware writer support and per-interface/link-type PCAPng IDs
5414ca59c3 Register capture formats and wireless observations through one resolution API
4189793955 Add opt-in Radiotap, including the short-preamble correction
6433d9e442 Preserve legacy write-hook dispatch for capture adapters

Architecture and compatibility

IPcapWriter gains writePacketWithPrefix(); custom implementations must
implement it. The migration guide documents prefix length semantics and the
PCAPng snaplen correction. PcapRecorder gains an opt-in NED parameter, and
.oppfeatures includes the wireless observation adapter package. No modeled
frame fields or MSG definitions change.

The existing packet-only PcapRecorder::writePacket hook runs once per selected
packet before adapter expansion, including when one A-MPDU produces several
records. Subclass filtering and replacement therefore apply to both plain and
Radiotap captures. Borrowed PHY context follows only the original packet;
replacement packets do not inherit it. Nested calls and exceptions restore the
previous observation context.

The PR touches the sealed src/inet/common/packet/recorder/ surface:
IPcapCaptureAdapter.h, IPcapWriter.h, PcapCaptureAdapterRegistry.{h,cc},
PcapRecorder.{h,cc,ned}, PcapWriter.{h,cc} and PcapngWriter.{h,cc}.
After the audit identified the sealed scope and the registry API correction, the
user requested “perform the corrections” and explicitly requested rewriting
the local commit messages and updating this description. That authorization
covers the named correction work; it does not remove the seal or substitute for
the repository's trusted, head-bound merge approval. Historical authorization
for the original sealed changes was not independently verified by this audit.
The subsequent legacy-hook correction in PcapRecorder.{h,cc} was also authorized
by the user after the finding and affected path were identified.

Scoped architecture checks found no new dependencies. Existing recorder
dependencies on node/interface abstractions remain covered by AV-ORG-01;
they have not been silently sanctioned or removed from the ledger.

Validation

The validated source is now committed at
6433d9e442f5abe7950c6d750f8c45516fcb4059, with tree
8a2979fa7fba28eddc522150fd175a4c497ead3e.
Run from the INET repository root, using OMNeT++ 6.4.0aipre2 and debug mode:

make MODE=debug -j8
MPLCONFIGDIR=/tmp/pr1130-matplotlib inet_run_unit_tests -m debug -f '(PcapCaptureAdapterRegistry|PcapRecorderFcsInd|PcapRecorderIeee80211Ampdu|PcapRecorderRadiotapHtVht|PcapWriterPrefix|PcapngWriterSnaplen|WirelessPcapCaptureObservationAdapter)_1\.test'
MPLCONFIGDIR=/tmp/pr1130-matplotlib inet_run_module_tests -m debug -f 'PcapRecorder(LegacyWriteHook|RadiotapRoundTrip)_1\.test'
git diff --check
doc/project/enforcement/check-architecture.sh src/inet/common/packet/recorder
  • Debug build: PASS.
  • Focused unit tests: 7/7 PASS, including long/short HR-DSSS preambles,
    independent FCS flags, both mode-tag types, and transmission precedence.
  • Module tests: 2/2 PASS. The round-trip test covers recorder/read/replay,
    default capture and conversion-disabled DLT 105 behavior. The new signal-driven
    legacy-hook test checks invocation, suppression, replacement bytes and
    preservation of the original packet in both plain and Radiotap captures.
    It failed before the fix because the Radiotap path never invoked the override.
  • The first four commits passed incremental debug builds and checks
    through the installed opp_repl API: respectively 1/1, 2/2, 4/4 and 7/7
    unit tests, plus 1/1 module test at 4189793955.
    Its exact commands and results are retained locally under
    audit/pull-request/pr-1130-evidence/corrections/.
  • Commit-message and classification checks passed for the latest commit;
    whitespace checks passed for its patch. The first four commits also passed
    include and NED-parameter checks. The latest scoped architecture check reports
    four pre-existing node/interface includes under open AV-ORG-01; no new
    dependencies were introduced.

Legacy fingerprints

Run from tests/fingerprint:

./fingerprinttest -d -t 8 -m '/(showcases/general/pcaprecording|examples/inet/pcaprecorder|examples/wireless/ieee80211)/' -f tplx -f '~tNl' -f '~tND' -l /tmp/pr1130-hook-fingerprint-details.log
./fingerprinttest -d -t 8 -m '/examples/wireless/ieee80211levelofdetail' -f tplx -f '~tNl' -f '~tND' -l /tmp/pr1130-hook-wifi-details.log

10/10 cases PASS, with no fingerprint baseline changes:

  • Two PCAP cases: examples/inet/pcaprecorder (General, run 0, 5000s) and
    showcases/general/pcaprecording (PcapRecording, run 0, 10s). The latter covers
    default-off IEEE 802.11 capture alongside Ethernet/PPP/IP and packet filtering.
  • Eight IEEE 802.11 level-of-detail cases: Default and Layered configurations,
    distances 100/1000, bitrates 6/54, repetition 0, one simulated second each.

The first selector's examples/wireless/ieee80211 alternative matches no rows;
the second command supplies the eight WLAN cases. These runs compare tplx,
~tNl and ~tND, using the checked-in run/seed selection.

IEEE 802.11-disabled build

An isolated checkout containing the same recorder source passed a debug build
with Ieee80211 and its dependent features disabled. From that checkout's root:

source setenv -q
opp_featuretool disable -f Ieee80211
make MODE=debug -j8

The repository's feature smoke simulation also passed. From its tests/features
directory, with the isolated checkout's environment active:

inet --debug -u Cmdenv -n . -f omnetpp.ini -c General -r 0

The smoke test verifies library loading and initialization. An initial invocation
omitted -n . and could not find FeatureTest; adding the local NED directory
resolved that setup error.

Logs, normalized test results, source hashes and the disabled feature configuration
are retained locally under audit/pull-request/pr-1130-evidence/legacy-hook/.
Release compilation, the complete feature matrix and the full legacy Wi-Fi suites
have not been rerun for this revision; the fingerprint result above is scoped to
the ten named cases.

@mgonzalezlopezudc
mgonzalezlopezudc marked this pull request as ready for review August 16, 2026 20:47

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

Comment thread src/inet/linklayer/ieee80211/pcap/Ieee80211RadiotapPcapCaptureAdapter.cc Outdated
@mgonzalezlopezudc

Copy link
Copy Markdown
Contributor Author

@levy With respect to the potential bug signaled by Devin in its review: "Large packets are now silently cut short in the default capture file format: Recorded packets are now shortened to the configured maximum capture size (std::min<size_t>(originalLength, snaplen) at src/inet/common/packet/recorder/PcapngWriter.cc:231) in the PCAPng format, which previously always stored them in full, so existing setups can lose the tail of every oversized frame. Impact: Users who kept the default settings and captured frames larger than the default limit will now find those frames incomplete in their capture files."

I think the right behavior for INET is to honor the value of snaplen. Maybe add a comment in WHATSNEW?

@mgonzalezlopezudc

Copy link
Copy Markdown
Contributor Author

@levy all Devin's comments have been addressed throughout the commits. PR ready for your review.

A finite snaplen previously had no effect on PCAPng output. Advertise and
enforce it while retaining the selected frame's original length. Zero
continues to mean unlimited. PcapngWriterSnaplen_1 covers selected ranges,
finite limits, unlimited capture and block padding.

Change: src.common.packet.recorder.PcapngWriter | behavior.change.fix | test whatsnew migration
Capture formats may carry metadata outside the selected packet bytes.
Write that prefix directly, including it in original and captured lengths,
without constructing another Packet. Require every writer to implement the
operation. PCAPng associates each interface and link type with its own ID
and resets those IDs when reopening a file. Prefix tests cover truncation,
multiple formats on one interface and reopening.

Change: src.common.packet.recorder | behavior.add | test whatsnew migration | radiotap-capture
Allow optional protocol adapters to select a link type and packet ranges
through generic registration points. Preserve the recorder's existing
subclass hooks and conversion-disabled behavior. Move direct Signal,
transmission and reception handling into the wireless feature so the
recorder no longer implements that translation. Registry and observation
tests accompany the infrastructure; adapters remain disabled by default.

Keep the resolved adapter with the protocol and offsets so production and
tests share one resolution API.

Change: src.common.packet.recorder | behavior.add | test whatsnew | radiotap-capture
Expose available legacy, HT and VHT SU metadata in capture files while
retaining bare MAC output by default. Split typed A-MPDUs into MPDUs and
preserve malformed aggregates as whole PSDUs. Honor FcsInd only for intact
imported MAC frames; selected ranges retain trailer-based FCS detection.
Field and aggregate tests accompany a signal-driven recorder/reader/replay
test, which preserves FCS presence even when imported frames are raw bytes.

Preserve the selected HR-DSSS short preamble in Radiotap Flags independently
of FCS. Cover request and indication tags and transmission precedence.

Change: src.ieee80211 | behavior.add | test whatsnew | radiotap-capture
Enabling Radiotap bypassed subclasses overriding the packet-only writePacket
overload, silently skipping their filtering or replacement logic. Invoke
that override before adapter record expansion and retain borrowed PHY
context only when the override forwards the original packet. Restore the
observation context after normal returns and exceptions.

Add a signal-driven module test that suppresses and replaces packets in
plain and Radiotap captures. Before the fix it fails because the Radiotap
recorder never invokes the legacy override.

Validation: debug build, seven capture unit tests, both recorder module
tests, and ten scoped legacy fingerprint cases passed. An isolated debug
build with Ieee80211 disabled and its feature smoke simulation also passed.
No fingerprint baselines changed.

Change: src.common.packet.recorder.PcapRecorder | behavior.change.fix | test | radiotap-capture
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant